package com.outdoor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.outdoor.exception.BusinessException;
import com.outdoor.model.dto.request.ApplicationRequest;
import com.outdoor.model.entity.Application;
import com.outdoor.model.entity.Team;
import com.outdoor.model.entity.User;
import com.outdoor.model.enums.ApplicationStatus;
import com.outdoor.mapper.ApplicationMapper;
import com.outdoor.service.ApplicationService;
import com.outdoor.service.TeamService;
import com.outdoor.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 申请服务实现
 * 
 * @author OutdoorTeam
 * @date 2025-05-18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ApplicationServiceImpl implements ApplicationService {

    private final ApplicationMapper applicationMapper;
    private final UserService userService;
    private final TeamService teamService;

    @Override
    public Application createApplication(ApplicationRequest request, Long userId) {
        User user = userService.getUserById(userId);
        Team team = teamService.getTeamById(request.getTeamId());
        
        // 检查团队是否已满
        List<Long> memberIds = teamService.getTeamMemberIds(team.getId());
        if (memberIds.size() >= team.getMaxMembers()) {
            throw new BusinessException("TEAM_FULL", "团队已满，无法申请加入");
        }
        
        // 检查用户是否已是团队成员
        if (memberIds.contains(userId)) {
            throw new BusinessException("ALREADY_MEMBER", "您已是团队成员，无需申请");
        }
        
        // 检查是否已有申请
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("user_id", userId).eq("team_id", team.getId());
        if (applicationMapper.selectCount(query) > 0) {
            throw new BusinessException("APPLICATION_EXISTS", "您已提交过申请，请勿重复提交");
        }
        
        Application application = Application.builder()
                .userId(userId)
                .teamId(team.getId())
                .experience(request.getExperience())
                .message(request.getMessage())
                .applyTime(LocalDateTime.now())
                .build();
        application.setStatus(ApplicationStatus.PENDING);
        
        applicationMapper.insert(application);
        log.info("用户 {} 申请加入团队 {} 成功", user.getUsername(), team.getName());
        
        return application;
    }

    @Override
    public Application processApplication(Long id, ApplicationStatus status, Long currentUserId) {
        Application application = getApplicationById(id);
        Team team = teamService.getTeamById(application.getTeamId());
        
        // 检查权限
        if (!team.getLeaderId().equals(currentUserId)) {
            throw new BusinessException("UNAUTHORIZED", "只有团队领队可以处理申请");
        }
        
        // 检查申请状态
        if (application.getStatus() != ApplicationStatus.PENDING) {
            throw new BusinessException("INVALID_STATUS", "只能处理待审核的申请");
        }
        
        // 如果批准申请，检查团队是否已满
        List<Long> memberIds = teamService.getTeamMemberIds(team.getId());
        if (status == ApplicationStatus.APPROVED && memberIds.size() >= team.getMaxMembers()) {
            throw new BusinessException("TEAM_FULL", "团队已满，无法批准申请");
        }
        
        application.setStatus(status);
        applicationMapper.updateById(application);
        
        // 如果批准申请，将用户添加到团队成员
        User applicant = userService.getUserById(application.getUserId());
        if (status == ApplicationStatus.APPROVED) {
            teamService.joinTeam(team.getId(), application.getUserId());
            log.info("申请已批准: 用户 {} 加入团队 {}", applicant.getUsername(), team.getName());
        } else {
            log.info("申请已拒绝: 用户 {} 加入团队 {}", applicant.getUsername(), team.getName());
        }
        
        return application;
    }

    @Override
    public Application getApplicationById(Long id) {
        Application application = applicationMapper.selectById(id);
        if (application == null) {
            throw new BusinessException("APPLICATION_NOT_FOUND", "申请不存在");
        }
        return application;
    }

    @Override
    public List<Application> getApplicationsByUser(Long userId) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("user_id", userId);
        return applicationMapper.selectList(query);
    }
    
    @Override
    public IPage<Application> getApplicationsByUserPage(Long userId, Page<Application> page) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("user_id", userId)
             .orderByDesc("apply_time");
        return applicationMapper.selectPage(page, query);
    }

    @Override
    public List<Application> getApplicationsByTeam(Long teamId) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("team_id", teamId);
        return applicationMapper.selectList(query);
    }
    
    @Override
    public IPage<Application> getApplicationsByTeamPage(Long teamId, Page<Application> page) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("team_id", teamId)
             .orderByDesc("apply_time");
        return applicationMapper.selectPage(page, query);
    }

    @Override
    public List<Application> getApplicationsByTeamAndStatus(Long teamId, ApplicationStatus status) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("team_id", teamId).eq("status", status.name());
        return applicationMapper.selectList(query);
    }
    
    @Override
    public IPage<Application> getApplicationsByTeamAndStatusPage(Long teamId, ApplicationStatus status, Page<Application> page) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("team_id", teamId)
             .eq("status", status.name())
             .orderByDesc("apply_time");
        return applicationMapper.selectPage(page, query);
    }

    @Override
    public boolean hasApplied(Long userId, Long teamId) {
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.eq("user_id", userId).eq("team_id", teamId);
        return applicationMapper.selectCount(query) > 0;
    }

    @Override
    public List<Application> getPendingApplicationsByUser(Long userId) {
        return applicationMapper.selectPendingByUser(userId);
    }
    
    @Override
    public IPage<Application> getPendingApplicationsByUserPage(Long userId, Page<Application> page) {
        return applicationMapper.selectPendingByUserPage(page, userId);
    }
    
    @Override
    public List<Application> getPendingApplicationsForManager(Long userId) {
        // 先获取用户管理的所有团队ID
        List<Long> teamIds = teamService.getTeamIdsByLeader(userId);
        if (teamIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 通过MyBatis-Plus的QueryWrapper进行查询
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.in("team_id", teamIds)
             .eq("status", ApplicationStatus.PENDING.name())
             .orderByDesc("apply_time");
             
        return applicationMapper.selectList(query);
    }
    
    @Override
    public IPage<Application> getPendingApplicationsForManagerPage(Long userId, Page<Application> page) {
        // 先获取用户管理的所有团队ID
        List<Long> teamIds = teamService.getTeamIdsByLeader(userId);
        if (teamIds.isEmpty()) {
            return page.setRecords(new ArrayList<>());
        }
        
        // 通过MyBatis-Plus的QueryWrapper进行查询
        QueryWrapper<Application> query = new QueryWrapper<>();
        query.in("team_id", teamIds)
             .eq("status", ApplicationStatus.PENDING.name())
             .orderByDesc("apply_time");
             
        return applicationMapper.selectPage(page, query);
    }
} 